package com.yunxin.core.application.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.yunxin.core.application.assembler.AreasAssembler;
import com.yunxin.core.application.dto.areas.AreasDTO;
import com.yunxin.core.application.dto.areas.AreasTwoLevelDTO;
import com.yunxin.core.application.service.AreasQueryService;
import com.yunxin.core.infra.persistence.entity.areas.AreasDO;
import com.yunxin.core.infra.persistence.mapper.areas.AreasExtendMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zero°
 * @since 2023-06-15
 */
@Service
@RequiredArgsConstructor
public class AreasQueryServiceImpl implements AreasQueryService {

    private final AreasExtendMapper areasExtendMapper;

    private final AreasAssembler areasAssembler;

    @Override
    public List<AreasTwoLevelDTO> listTwoLevelArea() {
        List<AreasDO> list = areasExtendMapper.listTwoLevelArea();
        List<AreasDTO>  results = list.stream().map(areasAssembler::toAreasResult).toList();
        List<AreasDTO> oneLevel = results.stream().filter(x -> CharSequenceUtil.isEmpty(x.getParentAreaCode())).toList();
        List<AreasDTO> twoLevel = results.stream().filter(x -> CharSequenceUtil.isNotEmpty(x.getParentAreaCode())).toList();
        Map<String, List<AreasDTO>> map = twoLevel.stream().collect(Collectors.groupingBy(AreasDTO::getParentAreaCode));
        return oneLevel.stream().map(x -> {
            AreasTwoLevelDTO dto = new AreasTwoLevelDTO();
            dto.setAreaName(x.getAreaName());
            dto.setAreaCode(x.getAreaCode());
            List<AreasDTO> areas = map.get(x.getAreaCode());
            if (CollUtil.isNotEmpty(areas)) {
                dto.setSubAreaList(areas.stream().map(sub->{
                    AreasTwoLevelDTO areasTwoLevelDTO = new AreasTwoLevelDTO();
                    areasTwoLevelDTO.setAreaCode(sub.getAreaCode());
                    areasTwoLevelDTO.setAreaName(sub.getAreaName());
                    areasTwoLevelDTO.setSubAreaList(Collections.emptyList());
                    return areasTwoLevelDTO;
                }).toList());
            }
            return dto;
        }).toList();
    }

    @Override
    public List<String> getAllCity() {
        return areasExtendMapper.listCityName();
    }
}
